クロスアカウントによるS3レプリケーションのパターン別設定方法
はじめに
異なるAWSアカウントによる同一リージョンでのS3レプリケーション(以下、SSR)は、2019年にリリースされました。
Amazon S3 introduces Same-Region Replication
実際に設定しようとしたところ、いくつか?になってハマってしまったので設定方法と注意事項をまとめました。
S3レプリケーションとは
S3バケット同士をレプリケーションしてくれる機能です。バケット全体または特定のプレフィックス、特定のタグが設定されたオブジェクトをレプリケーションできます。同一のAWSアカウントはもちろんのこと、異なるAWSアカウントのS3バケットとレプリケーションすることが可能です。同一AWSアカウントでのレプリケーションはこちらを参考にしてください。
前提条件
S3レプリケーションの前提としては、対象のS3バケット(レプリケーション元、レプリケーション先)でバージョンニング機能を有効にする必要があります。
それぞれのパターンでやってみる
パターン1 前提条件だけを設定したレプリケーション
まずは、前提条件であるバージョニング機能を有効にしてレプリケーションしてみます。S3バケットの設定は以下の通りです。
- バージョニング:有効
- パブリックアクセスブロック:すべてブロック
ソースバケットでレプリケーションルールを作成します。
- レプリケーションルール名:rule1
- ソースバケット:そのまま
- 送信先:アカウントIDはDestinationのAWSアカウント、バケット名は送信先S3バケット名
- IAMロール:新しいロールの作成(s3crr_role_for_ソースバケット名で作成される)
送信先S3バケット名でバケットポリシーを設定します。Principalで指定するのは、上記で作成されたIAMロールからReplicateを許可するポリシーです。
{ "Version": "2012-10-17", "Id": "Policy1618390254681", "Statement": [ { "Sid": "1", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::送信元AWSアカウントID:role/service-role/送信元AWSアカウントのIAMロール" }, "Action": [ "s3:ReplicateDelete", "s3:ReplicateObject" ], "Resource": "arn:aws:s3:::送信先S3バケット名/*" } ] }
ソースバケットにreplication-test.txtというファイルをアップロードしてみます。なお、アップロードしたファイルのプロパティからレプリケーションのステータスを確認することができます。レプリケーション中はPENDING
です。
レプリケーションが成功するとレプリケーションのステータスがCOMPLETED
となっていること、送信先バケットでファイルがあることが確認できます。
これでレプリケーションできました、、が!このレプリケーションルールだとファイルの所有者が送信元AWSアカウントとなります。アクセスコントール、暗号化の変更ができません。
パターン2 所有者の変更
パターン1をベースにレプリケーションする際に所有者を変更する為にレプリケーションルールを編集します。送信先の設定箇所にある「オブジェクト所有者を送信先バケット所有者に変更」をチェックします。
ソースバケットにreplication-test1.txtというファイルをアップロードしてみます。レプリケーションステータスを見るとFAILED
と表示されました。レプリケーションの失敗です。
これは送信元AWSアカウントのIAMロールから送信先S3バケットで所有者を変更する権限が、バケットポリシーに無い為、Aceess Deniedが発生しています。送信先S3バケットのバケットポリシーに所有者を変更できる権限(s3:ObjectOwnerOverrideToBucketOwner)を追記します。
{ "Version": "2012-10-17", "Id": "Policy1618390254681", "Statement": [ { "Sid": "1", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::送信元AWSアカウントID:role/service-role/送信元AWSアカウントのIAMロール" }, "Action": [ "s3:ReplicateDelete", "s3:ReplicateObject" ], "Resource": "arn:aws:s3:::送信先S3バケット名/*" }, { "Sid": "2", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::送信元AWSアカウントID:role/service-role/送信元AWSアカウントのIAMロール" }, "Action": "s3:ObjectOwnerOverrideToBucketOwner", "Resource": "arn:aws:s3:::送信先S3バケット名/*" } ] }
再度、ソースバケットにreplication-test1.txtというファイルをアップロードしてみるとレプリケーションスタータスがCOMPLETED
で送信先S3バケットに転送されました。また、所有者も変更されており、アクセスコントロール、暗号化を設定できるようになります。
パターン3 サーバ暗号化(SSE-S3)
今度はそれぞれのバケットで暗号化してみます。SSE-S3で暗号化します。
ソースバケットにreplication-test2.txtというファイルをアップロードしてみます。レプリケーションスタータスがCOMPLETEDで送信先S3バケットに転送されました。
パターン4 サーバ暗号化(KMS CMK)
次に送信先S3バケットだけ暗号化してみます。CMKで暗号化します。
ソースバケットにreplication-test3.txtというファイルをアップロードしてみます。レプリケーションステータスを見るとFAILEDと表示されました。レプリケーションの失敗です。
これは、送信元AWSアカウントのIAMロールがCMKのキーポリシーで許可されていない為、暗号化できずにエラーとなりました。キーポリシーの「"Sid": "Allow use of the key",」、「"Sid": "Allow attachment of persistent resources"」のPrincipalに送信元AWSアカウントのIAMロールARNを追加します。
また、送信元AWSアカウントのIAMロールでもCMKによる暗号化できるIAMポリシーを設定する必要があります。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "kms:Decrypt", "kms:Encrypt", "kms:RevokeGrant", "kms:GenerateDataKey", "kms:ReEncryptTo", "kms:GenerateDataKeyWithoutPlaintext", "kms:DescribeKey", "kms:GenerateDataKeyPairWithoutPlaintext", "kms:GenerateDataKeyPair", "kms:CreateGrant", "kms:ReEncryptFrom", "kms:ListGrants" ], "Resource": "arn:aws:kms:ap-northeast-1:送信先AWSアカウントID:key/CMKキーID" } ] }
再度、ソースバケットにreplication-test3.txtというファイルをアップロードしてみるとレプリケーションスタータスがCOMPLETEDで送信先S3バケットに転送されました。また、所有者も変更されており、CMKで暗号化されています。
まとめ
パターン毎に必要な権限が無いとレプリケーションできないことがわかりました。所有者を変更するかどうかは、レプリケーション対象のデータの取り扱いによって、変更不要の場合もあると思います。また、前提条件であるバージョニング機能が有効である為、オブジェクトのライフサイクルを意識しないと利用料があがってしまうことも注意が必要です。適切にライフサイクルポリシーを設定しましょう。